package com.snow.java.base.junit;

import com.snow.java.base.service.MyFun;
import com.snow.java.base.service.MyFun2;

import java.util.Comparator;
import java.util.function.Consumer;

/**
 * @类名称：MyLambda
 * @类描述：Lambda表达式解析
 * @author: bingHeng
 * @Date
 * @Version: 1.0
*/
public class MyLambda {
    public static void main(String[] args) {

        // Lambda语法1：无参数 -> 无返回值
        Runnable runnable = () -> System.out.println("hello lambda");
        runnable.run();

        // Lambda语法2：有一个参数 ->无返回值  (o1) -> System.out.println(o1)  简写成：System.out::println
        System.out.println("=============================");
        Consumer<String> con = System.out::println;
        con.accept("hello 2");

        // Lambda语法3：有两个参数，有返回值，并且lambda体中有多条语句
        Comparator<Integer> comparator = (o1, o2) -> {
            System.out.println("hello 3");
            return Integer.compare(o1, o2);
        };

        // Lambda语法4: 有两个参数，有返回值，并且有且只有一条语句，那么大括号和return都可以省略不写
        Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1, o2);

        // 语法4，进一步优化为：
        Comparator<Integer> comparator2 = Integer::compare;

        // lambda表达式的参数列表的数据类型可以省略不写，因为JVM编译器通过上下文推断出数据类型，即类型推断

        /**
         * 二：lambda表达式需要“函数式接口”的支持
         *  函数式接口：接口中只有一个抽象方法的接口，称为函数式接口，可以使用注解@FunctionalInterface 修饰
         *  @FunctionalInterface  可以检查该接口是否是函数式接口
         */

        Integer operation = operation(100, (o) -> o * o);
        System.out.println(operation);

        Long op = op(200L, 200L, (o1, o2) -> (long) Long.compare(o1, o2));
        System.out.println(op);
    }

    /**
     * 利用函数式接口和Lambda表达式，对一个数进行运算
     * @param num
     * @param myFun
     * @return
     */
    public static Integer operation(Integer num, MyFun myFun) {
        return myFun.getValue(num);
    }

    public static Long op(Long l1, Long l2, MyFun2<Long, Long> mf){
         return mf.getValue(l1, l2);
    }
}
